home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Source / collapse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-20  |  9.3 KB  |  321 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     collapse.c
  4.  
  5.     This module handles collapsing and expanding threads.
  6.     
  7.     Copyright © 1994-1995, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include "glob.h"
  12. #include "collapse.h"
  13. #include "menus.h"
  14. #include "newswatcher.h"
  15. #include "windutil.h"
  16. #include "dialog.h"
  17. #include "listutil.h"
  18. #include "help.h"
  19.  
  20.  
  21.  
  22.  
  23. /*----------------------------------------------------------------------------
  24.     ExpandCollapseThread 
  25.     
  26.     Expand or collapse a single thread.
  27.             
  28.     Entry:    wind = pointer to subject window.
  29.             theCell = any cell in the thread to be expanded or collapsed.
  30.             
  31.     Exit:    function result = true if thead collapsed, false if expanded.
  32. ----------------------------------------------------------------------------*/
  33.  
  34. Boolean ExpandCollapseThread (WindowPtr wind, Cell theCell)
  35. {
  36.     TWindow **info;
  37.     ListHandle theList;
  38.     TSubject **subjectArray, theSubject;
  39.     Cell tmpCell, newCell;
  40.     long finalTicks;
  41.     short i, nextInThread, cellDataLen, index;
  42.     Rect inval;
  43.     short visTopBeforeDelRow, visTopAfterDelRow;
  44.     
  45.     KillBalloon();
  46.     info = (TWindow**)GetWRefCon(wind);
  47.     theList = (**info).theList;
  48.     subjectArray = (**info).subjectArray;
  49.     cellDataLen = 2;
  50.     LGetCell(&index, &cellDataLen, theCell, theList);
  51.     theSubject = (*subjectArray)[index];
  52.     if (theSubject.threadOrdinal != 1) {
  53.         theCell.v -= theSubject.threadOrdinal-1;
  54.         LGetCell(&index, &cellDataLen, theCell, theList);
  55.         theSubject = (*subjectArray)[index];
  56.     }
  57.     theSubject.collapsed = !theSubject.collapsed;
  58.     nextInThread = index;
  59.     for (i = 0; i < theSubject.threadLength; i++) {
  60.         (*subjectArray)[nextInThread].collapsed = theSubject.collapsed;
  61.         nextInThread = (*subjectArray)[nextInThread].nextInThread;
  62.     }
  63.     (*subjectArray)[index].onlyRedrawTriangle = true;
  64.     (*subjectArray)[index].onlyRedrawCheck = false;
  65.     (*subjectArray)[index].drawTriangleFilled = true;
  66.     LDraw(theCell, theList);
  67.     (*subjectArray)[index].onlyRedrawTriangle = false;
  68.     (*subjectArray)[index].onlyRedrawCheck = true;
  69.     LDraw(theCell, theList);
  70.     (*subjectArray)[index].onlyRedrawTriangle = true;
  71.     (*subjectArray)[index].onlyRedrawCheck = false;
  72.     
  73.     if (theSubject.collapsed) {
  74.         visTopBeforeDelRow = (**theList).visible.top;
  75.         LDelRow(theSubject.threadLength-1, theCell.v+1, theList);
  76.         visTopAfterDelRow = (**theList).visible.top;
  77.         if (visTopBeforeDelRow != visTopAfterDelRow)
  78.             (*subjectArray)[index].onlyRedrawTriangle = false;
  79.         SetPt(&tmpCell, 0, 0);
  80.         if (!LGetSelect(true, &tmpCell, theList)) 
  81.             MyLSetSelect(true, theCell, theList);
  82.     } else {
  83.         LSetDrawingMode(false, theList);
  84.         LAddRow(theSubject.threadLength-1, theCell.v+1, theList);
  85.         newCell = theCell;
  86.         nextInThread = theSubject.nextInThread;
  87.         for (i = 1; i < theSubject.threadLength; i++) {
  88.             newCell.v++;
  89.             LSetCell(&nextInThread, 2, newCell, theList);
  90.             nextInThread = (*subjectArray)[nextInThread].nextInThread;
  91.         }
  92.         LSetDrawingMode(true, theList);
  93.         inval = wind->portRect;
  94.         inval.top = (**info).panelHeight + (theCell.v - (**theList).visible.top + 1) *
  95.             (**theList).cellSize.v;
  96.         inval.right -= 15;
  97.         inval.bottom -= 15;
  98.         InvalRect(&inval);
  99.     }
  100.     
  101.     Delay(8, &finalTicks);
  102.     (*subjectArray)[index].drawTriangleFilled = false;
  103.     LDraw(theCell, theList);
  104.     (*subjectArray)[index].onlyRedrawTriangle = false;
  105.     return theSubject.collapsed;
  106. }
  107.  
  108.  
  109.  
  110. /*----------------------------------------------------------------------------
  111.     RezoomSubjectWindow 
  112.     
  113.     Rezoom a subject window after a thread has been expanded if the
  114.     "Zoom windows" preference is turned on and the window is
  115.     not locked.
  116.             
  117.     Entry:    wind = pointer to subject window.
  118.             expanded = true if thread expanded, false if contracted.
  119.             
  120.     Exit:    function result = error code.
  121. ----------------------------------------------------------------------------*/
  122.     
  123. OSErr RezoomSubjectWindow (WindowPtr wind, Boolean expanded)
  124. {
  125.     TWindow **info;
  126.     ListHandle theList;
  127.     ControlHandle scrollBar;
  128.     OSErr err = noErr;
  129.     
  130.     info = (TWindow**)GetWRefCon(wind);
  131.     theList = (**info).theList;
  132.     scrollBar = (**theList).vScroll;
  133.     if (expanded && gPrefs.reZoomWindows && 
  134.         GetControlMaximum(scrollBar) > 0 && !(**info).windPosLocked) 
  135.     {
  136.         err = DoZoom(wind, inZoomOut);
  137.         if (err != noErr) return err;
  138.     } else {
  139.         SetWindowNeedsZooming(wind);
  140.     }
  141.     return noErr;
  142. }
  143.  
  144.  
  145.  
  146. /*----------------------------------------------------------------------------
  147.     DoExpandCollapseSelectedThread 
  148.     
  149.     Expand or collapse just the currently selected thread.
  150.             
  151.     Entry:    wind = pointer to subject window.
  152.     
  153.     Exit:    function result = error code.
  154. ----------------------------------------------------------------------------*/
  155.     
  156. OSErr DoExpandCollapseSelectedThread (WindowPtr wind)
  157. {
  158.     TWindow **info;
  159.     ListHandle theList;
  160.     TSubject **subjectArray;
  161.     Cell theCell, tmpCell;
  162.     short cellDataLen, index;
  163.     TSubject theSubject;
  164.     Boolean collapsed;
  165.     OSErr err = noErr;
  166.  
  167.     info = (TWindow**)GetWRefCon(wind);
  168.     theList = (**info).theList;
  169.     subjectArray = (**info).subjectArray;
  170.     SetPt(&theCell, 0, 0);
  171.     if (!LGetSelect(true, &theCell, theList)) return noErr;
  172.     tmpCell = theCell;
  173.     tmpCell.v++;
  174.     if (LGetSelect(true, &tmpCell, theList)) return noErr;
  175.     cellDataLen = 2;
  176.     LGetCell(&index, &cellDataLen, theCell, theList);
  177.     theSubject = (*subjectArray)[index];
  178.     if (theSubject.threadLength <= 1) return noErr;
  179.     collapsed = ExpandCollapseThread(wind, theCell);
  180.     err = RezoomSubjectWindow(wind, !collapsed);
  181.     if (err != noErr) return err;
  182.     return noErr;
  183. }
  184.  
  185.  
  186.  
  187. /*----------------------------------------------------------------------------
  188.     TriangleClick 
  189.     
  190.     Handle a click on a triangle thread control.
  191.             
  192.     Entry:    wind = pointer to subject window.
  193.             where = location of mouse down in local coordinates.
  194.             
  195.     Exit:    function result = error code.
  196.             *triangleClicked = true if triangle control clicked.
  197. ----------------------------------------------------------------------------*/
  198.  
  199. OSErr TriangleClick (WindowPtr wind, Point where, Boolean *triangleClicked)
  200. {
  201.     TWindow **info;
  202.     ListHandle theList;
  203.     TSubject **subjectArray, theSubject;
  204.     FontInfo fontInfo;
  205.     Cell theCell;
  206.     short index, cellDataLen;
  207.     Rect hitRect;
  208.     Boolean inHitRect, newInHitRect;
  209.     short visTop, cellHeight;
  210.     Boolean collapsed;
  211.     short panelHeight;
  212.     OSErr err = noErr;
  213.  
  214.     *triangleClicked = false;
  215.     info = (TWindow**)GetWRefCon(wind);
  216.     panelHeight = (**info).panelHeight;
  217.     theList = (**info).theList;
  218.     visTop = (**theList).visible.top;
  219.     cellHeight = (**theList).cellSize.v;
  220.     subjectArray = (**info).subjectArray;
  221.     GetFontInfo(&fontInfo);
  222.     SetRect(&hitRect, 0, 0, (**theList).indent.h + fontInfo.ascent, 0);
  223.     if (where.h > hitRect.right) return noErr;
  224.     if (!PtInListCell(where, theList)) return noErr;
  225.     theCell.h = 0;
  226.     theCell.v = (where.v - panelHeight)/cellHeight + visTop;
  227.     cellDataLen = 2;
  228.     LGetCell(&index, &cellDataLen, theCell, theList);
  229.     theSubject = (*subjectArray)[index];
  230.     if (theSubject.threadLength == 1 || theSubject.threadOrdinal > 1) 
  231.         return noErr;
  232.     (*subjectArray)[index].drawTriangleFilled = inHitRect =  true;
  233.     (*subjectArray)[index].onlyRedrawTriangle = true;
  234.     LDraw(theCell, theList);
  235.     hitRect.top = (theCell.v - visTop) * cellHeight + panelHeight;
  236.     hitRect.bottom = hitRect.top + cellHeight;
  237.     while (StillDown()) {
  238.         GetMouse(&where);
  239.         newInHitRect = PtInRect(where, &hitRect);
  240.         if (newInHitRect != inHitRect) {
  241.             (*subjectArray)[index].drawTriangleFilled = newInHitRect;
  242.             LDraw(theCell, theList);
  243.             inHitRect = newInHitRect;
  244.         }
  245.     }
  246.     if (!inHitRect) {
  247.         (*subjectArray)[index].drawTriangleFilled = false;
  248.         (*subjectArray)[index].onlyRedrawTriangle = false;
  249.         return noErr;
  250.     }
  251.     collapsed = ExpandCollapseThread(wind, theCell);
  252.     err = RezoomSubjectWindow(wind, !collapsed);
  253.     if (err != noErr) return err;
  254.     *triangleClicked = true;
  255.     return noErr;
  256. }
  257.  
  258.  
  259.  
  260. /*----------------------------------------------------------------------------
  261.     ExpandCollapseKey 
  262.     
  263.     Handle the Command-arrow key shortcuts for exanding and collapsing threads.
  264.             
  265.     Entry:    wind = pointer to subject window.
  266.             theChar = the character (left or right arrow).
  267.             
  268.     Exit:    function result = error code.
  269. ----------------------------------------------------------------------------*/
  270.  
  271. OSErr ExpandCollapseKey (WindowPtr wind, char theChar)
  272. {
  273.     TWindow **info;
  274.     ListHandle theList;
  275.     TSubject **subjectArray;
  276.     Cell theCell, cellToScrollIntoView;
  277.     short cellDataLen, index;
  278.     TSubject theSubject;
  279.     Boolean expand;
  280.     Boolean changed = false;
  281.     OSErr err = noErr;
  282.  
  283.     info = (TWindow**)GetWRefCon(wind);
  284.     theList = (**info).theList;
  285.     subjectArray = (**info).subjectArray;
  286.     expand = theChar == rightArrow;
  287.  
  288.     SetPt(&theCell, 0, 0);
  289.     SetPt(&cellToScrollIntoView, 0, 0);
  290.     while (true) {
  291.         if (!LGetSelect(true, &theCell, theList)) break;
  292.         cellDataLen = 2;
  293.         LGetCell(&index, &cellDataLen, theCell, theList);
  294.         theSubject = (*subjectArray)[index];
  295.         if (theSubject.threadLength > 1)
  296.             if (theSubject.collapsed && expand ||
  297.                 !theSubject.collapsed && !expand) 
  298.             { 
  299.                 ExpandCollapseThread(wind, theCell);
  300.                 if (!expand) {
  301.                     if (cellToScrollIntoView.v == 0 &&
  302.                         theCell.v >= (**theList).visible.top && 
  303.                         theCell.v < (**theList).visible.bottom)
  304.                     {
  305.                         cellToScrollIntoView.v = theCell.v - theSubject.threadOrdinal + 1;
  306.                     }
  307.                     theCell.v -= theSubject.threadOrdinal - 1;
  308.                 }
  309.                 if (!changed) changed = true;
  310.             }
  311.         theCell.v++;
  312.     }
  313.     if (changed) {
  314.         err = RezoomSubjectWindow(wind, expand);
  315.         if (err != noErr) return err;
  316.         if (cellToScrollIntoView.v != 0) 
  317.             MyLScrollCellIntoView(cellToScrollIntoView, theList);
  318.     }
  319.     return noErr;
  320. }
  321.